﻿using _698._45Tool.Utils;
using CommonServiceLocator;
using Communication;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Jn698._45GWTool.Communication;
using Jn698._45GWTool.Services;
using Jn698._45GWTool.Settings;
using Jn698._45GWTool.Views;
using nblTool.utils;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using TouchMvvm;
using WebFirst.Entities;
using WindowsFormsApp1.Utils;
using IOC = GalaSoft.MvvmLight.Ioc.SimpleIoc;

namespace Jn698._45GWTool.ViewModels.Controls
{
    public class ProxyTransmitViewModel:ViewModelBase
    {
        private GWCmdMakeUpService GWCmdMakeUpService = new GWCmdMakeUpService();
        private SerialPortHelper serialPortHelper = SerialPortHelper.Instance;
        private TcpHelper tcpHelper = TcpHelper.Instance;

        private ObservableCollection<GWCmdMakeUp> gWCmdMakeUpList;

		public ObservableCollection<GWCmdMakeUp> GWCmdMakeUpList
        {
			get { return gWCmdMakeUpList; }
			set { Set(ref gWCmdMakeUpList,value); }
		}

        public IEventAction[] DataGridActionsCommand { get; set; }
        public ProxyTransmitViewModel()
        {
            GWCmdMakeUpList=new ObservableCollection<GWCmdMakeUp>(GWCmdMakeUpService.SelectByOAD("090700FF"));
            this.DataGridActionsCommand = new IEventAction[]
            {
                new EventAction<object,DataGridCellEditEndingEventArgs>("CellEditEnding",DataGridCellEditEndingChanged),
               
            };
        }

        private void DataGridCellEditEndingChanged(object arg1, DataGridCellEditEndingEventArgs args)
        {
            if (args.EditAction == DataGridEditAction.Commit)
            {
                if (arg1 is DataGrid dataGrid)
                {
                    if (dataGrid.SelectedIndex>= GWCmdMakeUpList.Count)
                    {
                        return;
                    }
                    var el = args.EditingElement as TextBox;
                    GWCmdMakeUpList[dataGrid.SelectedIndex].DataValue = el.Text;
                    GWCmdMakeUpService.Update(GWCmdMakeUpList[dataGrid.SelectedIndex]);
                }
            }
        }

        private bool satae = true;

        public bool State
        {
            get { return satae; }
            set { Set(ref satae, value); }
        }

        private async Task awitTCPRecv(int timeOutSec)
        {
            using (var tokenSource = new CancellationTokenSource())
            {

                var startTime = DateTime.Now;
                while (true)
                {
                    if ((DateTime.Now - startTime) >= TimeSpan.FromSeconds(timeOutSec))
                    {
                        tokenSource.Cancel();
                    }
                    if (tokenSource.IsCancellationRequested)
                    {
                        return;
                    }
                    if (tcpHelper.isComplete == true)
                    {
                        return;
                    }
                    await Task.Delay(TimeSpan.FromMilliseconds(10));
                }
            }
        }

        public RelayCommand<int> MouseDoubleClickCommand
        {
            get
            {
                var command = new RelayCommand<int>((index) =>
                {
                    if (GWCmdMakeUpList[index].SubItemName.Equals("端口通信控制块"))
                    {
                        IOC.Default.Unregister<ProxyTransmitCommViewModel>();
                        IOC.Default.Unregister<GWCmdMakeUp>();
                        IOC.Default.Register<ProxyTransmitCommViewModel>();
                        IOC.Default.Register(()=> GWCmdMakeUpList[index]);
                        ProxyTransmitCommView proxyTransmitCommView = new ProxyTransmitCommView();

                        if (proxyTransmitCommView.ShowDialog()==true)
                        {
                            GWCmdMakeUpList[index].DataValue = ProxyTransmitCommViewModel.commControl;
                        }
                    }
                });
                return command;
            }
        }

        public RelayCommand SendCommand
        {
            get
            {
                var command = new RelayCommand(async () =>
                {
                    if (MainViewModel.selectedDevice == null)
                    {
                        MessageBox.Show("请选择设备");
                        return;
                    }
                    
                    switch (ServiceLocator.Current.GetInstance<MainViewModel>().SecuritySelectedIndex)
                    {

                        //明文+RN_MAC
                        case 2:
                        //明文+SID_MAC
                        case 3:
                        //密文+SID
                        case 4:
                        //密文+SID_MAC
                        case 5:
                            if (string.IsNullOrWhiteSpace(SendModule.SessionInitKey))
                            {
                                MessageBox.Show("请先建立应用连接");
                                return;
                            }
                            break;
                        //明文
                        case 0:
                        //明文+RN
                        case 1:
                        default:

                            break;
                    }


                    string frame = "";
                    string UserData = "";
                    byte[] byteAddress = StringUtils.strToHexByte(MainViewModel.selectedDevice.DeviceAddress);
                    List<byte> APDU;
                    var datas = GWCmdMakeUpList[1].DataValue.Split(',');
                    UserData = "090700"
                    + GWCmdMakeUpList[0].DataValue
                    + int.Parse(datas[0]).ToString("X2")
                    + int.Parse(datas[1]).ToString("X2")
                    + (int.Parse(datas[2])+5).ToString("X2")
                    + (int.Parse(datas[3]) + 1).ToString("X2")
                    + int.Parse(datas[4]).ToString("X2")
                    + int.Parse(GWCmdMakeUpList[2].DataValue).ToString("X4")
                    + int.Parse(GWCmdMakeUpList[3].DataValue).ToString("X4")
                    + (GWCmdMakeUpList[4].DataValue.Replace(" ","").Length/2).ToString("X2")
                    + GWCmdMakeUpList[4].DataValue.Replace(" ", "")
                    + "00";


                    APDU = MessageGenerationModule.GetSecuriityFrame(StringUtils.hexStringToBytes(UserData.Replace(" ", string.Empty)).ToList(), ServiceLocator.Current.GetInstance<MainViewModel>().SecuritySelectedIndex);
                    //定义临时字节列表
                    List<byte> temp = new List<byte>();

                    temp.Add(0x68);
                    //长度域
                    short length = (short)(2 + 1 + 1 + (short)byteAddress.Length + 1 + 2 + (short)APDU.Count + 2);
                    //FrameLen = string.Format("{0:X2}{1:X2}", length & 0x00ff, length >> 8);
                    byte[] byteLength = BitConverter.GetBytes(length);

                    temp.AddRange(byteLength);

                    //控制域

                    //byte control = StringUtils.string_2_BCD(Control)[0];
                    temp.Add(0x43);

                    //地址域
                    //服务器地址SA
                    byte addressLen = (byte)(byteAddress.Length - 1);
                    if (MainViewModel.selectedDevice.DeviceAddress.Contains("A") || MainViewModel.selectedDevice.DeviceAddress.Contains("a"))
                    {
                        addressLen |= 0x40;
                    }
                    switch (TerminalSettings.Instanse.LogicAddressSelected)
                    {
                        case 1:
                            addressLen |= 0x10;
                            break;
                        case 2:
                            addressLen |= 0x20;
                            break;
                        case 3:
                            addressLen |= 0x30;
                            break;
                        case 0:
                        default:
                            break;
                    }
                    temp.Add(addressLen);
                    //temp.Add((byte)(byteAddress.Length - 1));

                    Array.Reverse(byteAddress);
                    temp.AddRange(byteAddress);

                    //客户机地址CA
                    byte ca = 0x11;
                    temp.Add(ca);

                    //帧头校验HCS
                    //HCS = ByteUtils.bytesToHexString(CheckSum.CRC16(temp, 1));
                    temp.AddRange(CheckSum.CRC16(temp, 1));

                    //链路用户数据
                    temp.AddRange(APDU);

                    //帧校验FCS
                    //FCS = ByteUtils.bytesToHexString(CheckSum.CRC16(temp, 1));
                    temp.AddRange(CheckSum.CRC16(temp, 1));

                    //结束字符
                    temp.Add(0x16);
                    frame = ByteUtils.bytesToHexString(temp);

                    State = false;
                    byte[] b = StringUtils.hexStringToBytes(frame);
                    string msgStr = "";
                    for (int i = 0; i < b.Length; i++)
                    {
                        msgStr += b[i].ToString("X2") + " ";
                    }
                    Messenger.Default.Send<string>($"发送帧({DateTime.Now.ToString()})：{msgStr}", "SendMessage");
                    switch (CommViewModel.selectedCommType)
                    {
                        case "串口":
                            serialPortHelper.SendDataMethod(b);
                            Messenger.Default.Send<string>($"({DateTime.Now.ToString()})：等待设备返回结果中...", "Info");
                            bool flag = false;
                            await Task.Run(() => flag=serialPortHelper.DataReceiveFunction());
                            if (!flag)
                            {
                                Messenger.Default.Send<string>($"({DateTime.Now.ToString()})：设备响应超时", "Info");
                            }
                            break;
                        case "GPRS":
                            tcpHelper.isComplete = false;
                            tcpHelper.SendData(MainViewModel.selectedDevice.DeviceAddress, b);
                            Messenger.Default.Send<string>($"({DateTime.Now.ToString()})：等待设备返回结果中...", "Info");
                            await awitTCPRecv(int.Parse(GWCmdMakeUpList[2].DataValue));
                            if (tcpHelper.isComplete==false)
                            {
                                Messenger.Default.Send<string>($"({DateTime.Now.ToString()})：设备响应超时", "Info");
                            }
                            break;
                        default:
                            break;
                    }
                    /*                    serialPortHelper.SendDataMethod(b);
                                        bool result = false;
                                        await Task.Run(() => result = serialPortHelper.DataReceiveFunction());*/
                    State = true;
                });
                return command;
            }
        }

    }
}
